  <!--
    - 云打印交互协议（https://support-cnkuaidi.taobao.com/doc.htm#?docId=107014&docType=1）
    - 云打印客户端打单测试页面（http://cdn-cloudprint.cainiao.com/waybill-print/docs/test/test_print.html?spm=a219a.7386653.0.0.111e669aNJG3s9）
    - 菜鸟自定义模板电子面单用户操作（https://cloudprint.cainiao.com/print/login.vm?__output_charset=gbk&targetURL=https%3A%2F%2Fcloudprint.cainiao.com%2Fprint%2Ftemplates.htm）
    - isv动态表格打印项示例（https://support-cnkuaidi.taobao.com/docs/doc.htm?treeId=493&articleId=107812&docType=1）
    - 云打印组件如何支持分页打印（https://support-cnkuaidi.taobao.com/support/hotProblemDetail.htm?spm=a219a.7386653.0.0.111e669aNJG3s9&source=search&id=297651&docType=14）
   -->
<template>
  <div>
    <el-steps class="mtb10" :active="active" align-center finish-status="success">
      <el-step title="选择打印机" />
      <el-step :title="titleTemplate" />
      <el-step title="选择自定义模板" />
    </el-steps>
    <div class="container">
      <el-radio-group v-show="active === 1" v-model="defaultPrinter">
        <el-radio v-for="item in printersList" :key="item.name" class="list-item" :label="item.name">{{ item.name }}</el-radio>
      </el-radio-group>
      <el-radio-group v-show="active === 2" v-model="standard">
        <el-radio v-for="item in standardTemplate" :key="item.standardTemplateName" class="list-item" :label="item.standardTemplateUrl">{{ item.standardTemplateName }}</el-radio>
      </el-radio-group>

      <div v-show="active === 3" class="custom">
        <template v-if="customTemplate.length > 0">
          <el-form ref="form" label-width="80px">
            <el-form-item label="固定项目">
              <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">全选</el-checkbox>
              <div style="margin: 15px 0;" />
              <el-checkbox-group v-model="checkedProject" @change="handleCheckedProject">
                <el-checkbox v-for="project in inherentProject" :key="project.value" :label="project.value">{{ project.lable }}</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item label="任意内容">
              <el-input v-model="desc" type="text" placeholder="请输入内容" maxlength="26" show-word-limit /></el-form-item>
          </el-form>
        </template>
        <span v-if="noCustomTemplate" class="no-data">暂无自定义面单模板数据，点击下方 <i class="tip">打印</i> 按钮即可</span>
      </div>
    </div>
    <el-row class="btn-main">
      <el-button v-if="active === 2 || active === 3" @click="lastStep">上一步</el-button>
      <el-button v-if="active === 1 || active === 2" @click="next">下一步</el-button>
      <el-button v-if="active === 3" type="primary" @click="processingData">打印</el-button>
    </el-row>
  </div>
</template>

<script>
import { getPrintTemplate, printCount } from '@/api/outStorage'
export default {
  name: 'Printing',
  props: {
    // 要打印的数据
    printData: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 哪家快递，比如，EMS、圆通、申通、顺丰等
    parcelType: {
      type: String,
      required: true
    },
    // 打印步骤第二步的页面文案
    titleTemplate: {
      type: String,
      default: '选择标准面单模板'
    }
  },
  data() {
    return {
      socket: null,
      active: 1, // 步骤
      defaultPrinter: '', // 默认选中的打印机
      printersList: [], // 所有的打印机
      standard: '', // 选择的标准面单模板
      standardTemplate: [], // 标准面单模板列表
      custom: {}, // 选择的自定义面单模板
      customTemplate: [], // 自定义面单模板列表
      noCustomTemplate: false, // 自定义面单模板是否为空
      checkAll: false,
      isIndeterminate: true,
      checkedProject: ['goodCode', 'goodsName', 'spec', 'quantity', 'goodsBarCode', 'wavePickingCode', 'orderNum'],
      desc: '',
      externalData: ['sourcePlatformName', 'wavePickingCode'], // 在第一层的数据里
      inherentProject: [{
        lable: '编码',
        value: 'goodCode'
      }, {
        lable: '名称',
        value: 'goodsName'
      }, {
        lable: '规格',
        value: 'spec'
      }, {
        lable: '数量',
        value: 'quantity'
      }, {
        lable: '条码',
        value: 'goodsBarCode'
      }, {
        lable: '波次号',
        value: 'wavePickingCode'
      }, {
        lable: '打印顺序',
        value: 'orderNum'
      }, {
        lable: '订单来源',
        value: 'sourcePlatformName'
      }],
      printNum: 0 // 打印次数
    }
  },
  watch: {
    active(val) {
      if (val === 2 && this.standardTemplate.length === 0) {
        this.getTemplate({
          type: 0,
          code: this.parcelType
        })
      }
      if (val === 3 && this.customTemplate.length === 0) {
        this.setPrinterConfig()
        this.getTemplate({
          type: 1,
          code: 'zdy'
        })
      }
    }
  },
  created() {
    this.initsocket()
    this.printData2 = JSON.parse(JSON.stringify(this.printData))
  },
  destroyed() {
    // this.socket && this.socket.close()
  },
  methods: {
    // 下一步
    next() {
      if (this.active === 2) {
        if (this.standard === '') {
          this.$message.error('必须要选择一个标准面单模板！')
          return
        }
      }
      this.active = this.active + 1
    },
    // 上一步
    lastStep() {
      this.active = this.active - 1
    },
    // 全选与否
    handleCheckAllChange(val) {
      const arr = []
      if (val) {
        for (const item of this.inherentProject) {
          arr.push(item.value)
        }
      }
      this.checkedProject = arr
      this.isIndeterminate = false
    },
    // 复选框点击
    handleCheckedProject(value) {
      const checkedCount = value.length
      this.checkAll = checkedCount === this.inherentProject.length
      this.isIndeterminate = checkedCount > 0 && checkedCount < this.inherentProject.length
    },
    // 初始化WebSocket
    initsocket() {
      this.socket = new WebSocket('ws://localhost:13528')
      // 建立连接
      this.socket.onopen = e => {
        console.log('Socket连接成功--->', e)
        this.getPrinters()
      }
      // 接受服务器返回的信息
      this.socket.onmessage = e => {
        console.log('received--->', e.data)
      }
      // 关闭连接
      this.socket.onclose = e => {
        console.warn('socket连接已关闭--->', e)
      }
      // 连接错误
      this.socket.onerror = e => {
        this.$message.error('无法打印，请打开《CAINIAO打印组件》重试！')
        console.error('socket连接发生错误--->', e)
      }
    },
    // 获取打印机列表
    getPrinters() {
      const parms = {
        cmd: 'getPrinters',
        requestID: this.getUUID(8, 10),
        version: '1.0'
      }
      this.socket.send(JSON.stringify(parms))
      this.socket.onmessage = (e) => {
        const data = JSON.parse(e.data)
        if (data.cmd === 'getPrinters') {
          this.printersList = data.printers
          this.defaultPrinter = data.defaultPrinter
        }
      }
    },
    // 设置打印机配置
    setPrinterConfig() {
      const parms = {
        cmd: 'setPrinterConfig',
        requestID: this.getUUID(8, 10),
        version: '1.0',
        printer: {
          name: this.defaultPrinter,
          needTopLogo: false,
          needBottomLogo: false,
          horizontalOffset: 0.5,
          verticalOffset: 0.7,
          forceNoPageMargins: true,
          autoPageSize: true,
          orientation: 0,
          autoOrientation: false,
          paperSize: {
            width: 100,
            height: 180
          }
        }
      }
      this.socket.send(JSON.stringify(parms))
    },
    // 处理要打印的数据
    processingData() {
      for (const item of this.printData) {
        const documents = []
        const printObject = {
          cmd: 'print',
          requestID: new Date().getTime(),
          version: '1.0',
          task: {
            taskID: this.getUUID(8, 10),
            preview: false,
            printer: this.defaultPrinter,
            notifyMode: 'allInOne',
            previewType: 'pdf',
            documents: []
          }
        }
        const result = item.printData ? JSON.parse(item.printData) : null
        const expressBillData = {
          documentID: item.code,
          contents: [
            {
              data: {
                recipient: {
                  address: {
                    detail: item.receiverDetailAddress
                    // city: item.receiverCity,
                    // detail: item.receiverDetailAddress,
                    // district: item.receiverDistrict,
                    // province: item.receiverProvince,
                    // town: item.receiverTown || ''
                  },
                  mobile: item.receiverMobile,
                  name: item.receiverName,
                  phone: ''
                },
                routingInfo: result ? result.data.routingInfo : {},
                sender: {
                  address: {
                    city: item.senderCity,
                    detail: item.senderDetailAddress,
                    district: item.senderDistrict,
                    province: item.senderProvince,
                    town: item.senderTown || ''
                  },
                  mobile: item.senderMobile,
                  name: item.senderName,
                  phone: ''
                },
                waybillCode: item.waybillCode
              },
              templateURL: this.standard
            }
          ]
        }
        if (this.checkedProject.length > 0 || this.desc !== '') {
          const arr = []
          const goodsContent = []
          item.deliveryItemVOList.forEach(goods => {
            for (const project of this.checkedProject) {
              if (!this.externalData.includes(project)) {
                if (project === 'quantity') {
                  goodsContent.push(`${goods[project]}*${goods.goodsUnitName}`)
                } else {
                  if (goods[project] !== '') {
                    goodsContent.push(goods[project])
                  }
                }
              }
            }
          })
          arr.push(goodsContent.join(' '))

          for (const project of this.checkedProject) {
            if (this.externalData.includes(project)) {
              if (!['wavePickingCode', 'orderNum', 'sourcePlatformName'].includes(project)) {
                arr.push(item[project] || '')
              }
            }
          }
          const customContent = arr.filter(function(s) {
            return s
          })
          const info = {
            data: {
              info: `${customContent.join('，')} ${this.desc} `
            },
            templateURL: this.customTemplate[0].standardTemplateUrl
          }
          if (this.checkedProject.includes('wavePickingCode')) {
            info.data.wavePickingCode = `波次号：${item.wavePickingCode}`
          }
          if (this.checkedProject.includes('orderNum')) {
            info.data.orderNum = `打印顺序：${item.orderNum || ''}`
          }
          if (this.checkedProject.includes('sourcePlatformName')) {
            info.data.source = `订单来源：${item.sourcePlatformName || ''}`
          }
          expressBillData.contents.push(info)
        }
        documents.push(expressBillData)
        printObject.task.documents = documents
        this.startPrinting(printObject)
      }
    },
    // 开始打印
    startPrinting(printObject) {
      console.log('即将打印的数据---->', JSON.stringify(printObject))
      this.socket.send(JSON.stringify(printObject))
      this.socket.onmessage = (res) => {
        const printResult = JSON.parse(res.data)
        if (printResult.cmd === 'print' && printResult.status === 'failed') {
          this.$message.error(printResult.msg)
        }
        if (printResult.cmd === 'print' && printResult.status === 'success') {
          this.printNum = ++this.printNum
          if (this.printNum === this.printData2.length) {
            this.$message.success('打印任务成功执行完毕')
            this.$eventBus.$emit('printFinish')
          }
          this.updatePrintCount(this.printData2[this.printNum - 1].code)
        }
        console.log('打印结果---->', res.data)
        this.$emit('finshPrint', res.data)
      }
      // const printData = { 'cmd': 'print', 'requestID': '123458666', 'version': '1.0', 'task': { 'taskID': '729666666', 'preview': true, 'printer': '', 'notifyMode': 'allInOne', 'previewType': 'pdf', 'documents': [{ 'documentID': '012345678555', 'contents': [{ 'data': { 'recipient': { 'address': { 'city': '杭州市', 'detail': '良睦路999号乐佳国际大厦2号楼小邮局', 'district': '余杭区', 'province': '浙江省', 'town': '' }, 'mobile': '13012345678', 'name': '菜鸟网络', 'phone': '057112345678' }, 'routingInfo': { 'routeCode': '123A-456-789' }, 'sender': { 'address': { 'city': '杭州市', 'detail': '文一西路1001号阿里巴巴淘宝城5号小邮局', 'district': '余杭区', 'province': '浙江省', 'town': '' }, 'mobile': '13012345678', 'name': '阿里巴巴', 'phone': '057112345678' }, 'waybillCode': '0123456999' }, 'templateURL': 'http://cloudprint.cainiao.com/template/standard/290659/44' }, { 'templateURL': 'http://cloudprint.cainiao.com/template/customArea/13450842/4' }] }] }}
    },
    // 获取打印模板
    getTemplate(parms) {
      getPrintTemplate(parms).then(res => {
        if (parms.type === 0) {
          this.standardTemplate = res.data || []
          // this.standardTemplate = [{ 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '邮政包裹蓝牙一联单', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/308720/5', 'standardWaybillType': '8' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '快递包裹一联单（高度130）', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/304351/5', 'standardWaybillType': '6' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹标准面单(蓝牙版)', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/286357/1', 'standardWaybillType': '7' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹便携式模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/286704/5', 'standardWaybillType': '3' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹一联单', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/275609/14', 'standardWaybillType': '6' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹标准三联模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/75704/41', 'standardWaybillType': '2' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹标准模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/801/148', 'standardWaybillType': '1' }, { 'code': 'HTKY', 'remarks': '', 'standardTemplateName': '百世快递标准模板(蓝牙版)', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/285199/4', 'standardWaybillType': '7' }, { 'code': 'HTKY', 'remarks': '', 'standardTemplateName': '百世快递便携式模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/278380/8', 'standardWaybillType': '3' }, { 'code': 'HTKY', 'remarks': '', 'standardTemplateName': '百世快递一联单（新）', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/278716/36', 'standardWaybillType': '6' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '邮政包裹蓝牙一联单', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/308720/5', 'standardWaybillType': '8' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '快递包裹一联单（高度130）', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/304351/5', 'standardWaybillType': '6' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹标准面单(蓝牙版)', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/286357/1', 'standardWaybillType': '7' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹便携式模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/286704/5', 'standardWaybillType': '3' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹一联单', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/275609/14', 'standardWaybillType': '6' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹标准三联模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/75704/41', 'standardWaybillType': '2' }, { 'code': 'POSTB', 'remarks': '', 'standardTemplateName': '中国邮政快递包裹标准模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/801/148', 'standardWaybillType': '1' }, { 'code': 'HTKY', 'remarks': '', 'standardTemplateName': '百世快递标准模板(蓝牙版)', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/285199/4', 'standardWaybillType': '7' }, { 'code': 'HTKY', 'remarks': '', 'standardTemplateName': '百世快递便携式模板', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/278380/8', 'standardWaybillType': '3' }, { 'code': 'HTKY', 'remarks': '', 'standardTemplateName': '百世快递一联单（新）', 'standardTemplateUrl': 'http://cloudprint.cainiao.com/template/standard/278716/36', 'standardWaybillType': '6' }]
        } else {
          const data = res.data.filter(item => Number(item.standardWaybillType) === 4)
          this.customTemplate = data
          if (data.length === 0) {
            this.noCustomTemplate = true
          }
        }
      })
    },
    // 获取请求的UUID，指定长度和进制，如 getUUID(8, 2)   //"01001010" 8 character (base=2)
    getUUID(len, radix) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
      var uuid = []; var i
      radix = radix || chars.length
      if (len) {
        for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
      } else {
        var r
        uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
        uuid[14] = '4'
        for (i = 0; i < 36; i++) {
          if (!uuid[i]) {
            r = 0 | Math.random() * 16
            uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r]
          }
        }
      }
      return uuid.join('')
    },
    // 面单打印次数
    updatePrintCount(deliveryCode) {
      return printCount(deliveryCode).then(res => {
        console.log('面单打印次数 +1 ---->', deliveryCode)
      })
    }
  }
}
</script>
<style scoped>
.mtb10 {
  margin: 20px 0 10px 0;
}
.container{
  max-height: 320px;
  overflow: auto;
  margin-top: 40px;
  margin-left: 56px;
}
.btn-main {
  position: absolute;
  right: 50px;
  bottom: 7px;
}
.list-item {
  display: block;
  margin: 10px 0;
}
.tip {
  font-size: 15px;
  font-weight: bold;
}
.custom {
    margin-left: -8px;
    margin-right: 20px;
}
.no-data {
    margin-left: 10px;
}
</style>
